/*
 * GDevelop C++ Platform
 * Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
 * reserved. This project is released under the MIT License.
 */
#ifndef MUSIC_H
#define MUSIC_H
#include <SFML/Audio.hpp>
#include <string>
#include "GDCpp/Runtime/String.h"

/**
 * \brief Represents a music to be played
 *
 * \see SoundManager
 * \ingroup SoundEngine
 */
class GD_API Music {
 public:
  Music();
  virtual ~Music(){};

  /**
   * \brief Open the music from a file.
   *
   * Example :
   * \code
   * Music myMusic;
   * myMusic.OpenFromFile("sound.ogg");
   * myMusic.Play();
   * \endcode
   */
  bool OpenFromFile(const gd::String& filename);

  /**
   * \brief Change music buffer.
   *
   * You must call OpenFromMemory after to use this buffer.
   */
  void SetBuffer(const char* newbuffer, std::size_t size);

  /**
   * Open music stored in buffer.
   * \param size The buffer size.
   */
  bool OpenFromMemory(std::size_t size);

  sf::Music music;  ///< SFML Music
  char* buffer;     ///< Music buffer when music have been loaded from memory

  /**
   * \brief Play the music.
   */
  void Play();

  /**
   * \brief Pause the music.
   */
  void Pause();

  /**
   * \brief Stop the music.
   */
  void Stop();

  /**
   * \brief Get the music status
   * \return sf::Music::Paused, sf::Music::Playing or sf::Music::Stopped.
   */
  inline sf::Music::Status GetStatus() const { return music.getStatus(); };

  /**
   * Make music looping or not.
   * \param loop true to activate looping.
   */
  void SetLoop(bool loop);

  /**
   * \brief Change the music volume.
   * \param volume The new volume, between 0 and 100.
   */
  void SetVolume(float volume_, float globalVolume);

  /**
   * \brief Get the music volume.
   */
  inline float GetVolume() const { return volume; }

  /**
   * \brief Change the music pitch.
   */
  void SetPitch(float newPitch) { music.setPitch(newPitch); };

  /**
   * \brief Get the music pitch.
   */
  float GetPitch() const { return music.getPitch(); };

  /**
   * \brief Change the current playing position of the music.
   * \param timeOffset The new playing position, in seconds.
   */
  void SetPlayingOffset(double timeOffset) {
    music.setPlayingOffset(sf::seconds(timeOffset));
  };

  /**
   * \brief Return the current playing position of the music, in seconds.
   */
  double GetPlayingOffset() const {
    return music.getPlayingOffset().asSeconds();
  };

  /**
   * \brief Internal member functions to update music volume according to global
   * volume.
   *
   * Called by the sound manager when the global volume is updated.
   */
  void UpdateVolume(float globalVolume);

#if defined(GD_IDE_ONLY)
  gd::String file;  ///< Only useful for GD debugger
#endif

 private:
  float volume;  ///< Music volume
};

#endif  // MUSIC_H
